const express = require("express");
const router = express.Router();
const { Config } = require("../../models");

const { NotFound } = require("http-errors");
const { success, failure } = require("../../utils/responses");
const net = require("net");

/**
 * 查询ip配置列表
 * GET /admin/ipConfig
 */
router.get("/", async (req, res, next) => {
  try {
    const query = req.query;
    const currentPage = Math.abs(Number(query.currentPage)) || 1;
    const pageSize = Math.abs(Number(query.pageSize)) || 10;
    const offset = (currentPage - 1) * pageSize;

    const condition = {
      where: {},
      // order: [['id', 'DESC']],
      limit: pageSize,
      offset: offset,
    };

    const { count, rows } = await Config.findAndCountAll(condition);

    success(req, res, "查询ip配置列表成功。", {
      list: rows,
      pagination: {
        total: count,
        currentPage,
        pageSize,
      },
    });
  } catch (error) {
    failure(req, res, error);
  }
});
/**
 * 查询ip配置列表详情
 * GET /admin/ipConfig
 */
router.get("/:id", async (req, res, next) => {
  try {
    const configDetail = await getConfig(req);
    success(req, res, "查询ip配置成功。", {
      configDetail,
    });
  } catch (error) {
    failure(req, res, error);
  }
});
/**
 * 更新ip配置
 * PUT /admin/ipConfig
 */
router.put("/:id", async (req, res, next) => {
  try {
    const configDetail = await getConfig(req);
    const body = await filterBody(req);
    const validate = await validateBody(body);
    if (validate) {
      await configDetail.update(body);
      success(req, res, "更新ip配置成功。", {
        configDetail,
      });
    }
  } catch (error) {
    failure(req, res, error);
  }
});

/**
 * 创建ip配置
 * POST /admin/ipConfig
 */
router.post("/", async (req, res, next) => {
  try {
    const body = await filterBody(req);

    const configDetail = await Config.create(body);
    success(req, res, "创建ip配置成功。", {
      configDetail,
    });
  } catch (error) {
    failure(req, res, error);
  }
});

/**
 * 公共方法：查询当前用户
 */
async function getConfig(req) {
  const { id } = req.params;

  const configDetail = await Config.findByPk(id);

  const { ip, port } = configDetail.dataValues;
  if (!configDetail) {
    throw new NotFound(`ID: ${id}的ip配置表未找到。`);
  }

  return configDetail;
}

/**
 * 公共方法：白名单过滤
 * @param req
 * @returns
 */
async function filterBody(req) {
  return {
    ip: req.body.ip,
    port: req.body.port,
    status: req.body.status,
    type: req.body.type,
    beUsed: req.body.beUsed,
  };
}
async function validateBody(body) {
  // const body = await filterBody(req);
  const { ip, port, status, type, beUsed } = body;
  if (!ip || !port) {
    throw new NotFound("ip 或 port 不能为空。");
  }
  const ipReg =
    /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/;
  if (!ipReg.test(ip)) {
    throw new NotFound("ip 格式不正确。");
  }
  const portReg =
    /^(?:[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;
  if (!portReg.test(port)) {
    throw new NotFound("port 格式不正确。");
  }
  if (port < 1 || port > 65535) {
    throw new NotFound("port 必须在1-65535之间。");
  }
  if (!status) {
    throw new NotFound("status 不能为空。");
  }
  if (!type) {
    throw new NotFound("type 不能为空。");
  }
  if (!beUsed) {
    throw new NotFound("beUsed 不能为空。");
  }

  return true;
}
/**
 * 测试ip 是否通信
 */

router.get("/test/:id", async (req, res, next) => {
  try {
    const configDetail = await getConfig(req);

    const connectResult = await testIpConnect(
      configDetail.ip,
      configDetail.port
    );

    if (!connectResult) {
      throw new NotFound(
        `IP: ${configDetail.ip}端口: ${configDetail.port}不可连接。`
      );
    }
    if (connectResult) {
      success(req, res, "连接成功", {});
    }
  } catch (error) {
    failure(req, res, error);
  }
});

async function testIpConnect(ip, port) {
  const client = new net.Socket();
  return new Promise((resolve, reject) => {
    const connectionTimeout = 10000; // 默认5秒
    // 添加超时强制中断
    let connectTimer = client.setTimeout(connectionTimeout, () => {
      client.destroy();
      clearTimeout(connectTimer);
      resolve(false);
      // this.emit('timeout', { id: this.id, error: 'Connection timeout', status: 0, ip: this.ip, port: this.port });
    });
    client.connect(port, ip, () => {
      resolve(true);
      client.destroy();
      console.log(`${ip}:${port}连接成功。`);
    });
    client.on("error", (err) => {
      resolve(false);
      console.log(`${ip}:${port}连接失败。`);
      client.destroy();
    });
    client.on("timeout", () => {
      resolve(false);
      console.log(`${ip}:${port}连接超时。`);
      client.destroy();
    });
  });
}

module.exports = router;
